'use strict';
// 参考 egg-router https://github.com/eggjs/egg-router/blob/512808fc1b9b0b3236e906a7b770f722b181bdcc/lib/egg_router.js
const is = require('is-type-of');
const inflection = require('inflection');

// 规则
const REST_MAP = {
  find: {
    suffix: '',
    method: 'GET',
  },
  get: {
    member: true,
    suffix: ':id',
    method: 'GET',
  },
  create: {
    suffix: '',
    method: 'POST',
  },
  patch: {
    member: true,
    suffix: ':id',
    method: 'PATCH',
  },
  remove: {
    member: true,
    suffix: ':id',
    method: 'DELETE',
  },
};

function resolveController(controller, app) {
  if (is.string(controller)) {
    const actions = controller.split('.');
    let obj = app.controller;
    actions.forEach(key => {
      obj = obj[key];
      if (!obj) throw new Error(`controller '${controller}' not exists`);
    });
    controller = obj;
  }
  // ensure controller is exists
  if (!controller) throw new Error('controller not exists');
  return controller;
}

function spliteAndResolveRouterParams({ args, app }) {
  let prefix;
  let middlewares;
  if (args.length >= 3 && (is.string(args[1]) || is.regExp(args[1]))) {
    // app.get(name, url, middleware, middleware, middleware, controller)
    prefix = args.slice(0, 2);
    middlewares = args.slice(2);
  } else {
    // app.get(url, middleware, middleware, controller)
    prefix = args.slice(0, 1);
    middlewares = args.slice(1);
  }
  // 加载 controller
  const controller = middlewares.pop();
  middlewares.push(resolveController(controller, app));
  return { prefix, middlewares };
}

function restful(...args) {
  // 分析配置，拿到: prefix (name url),  middlewares (...middleware, controller)
  const splited = spliteAndResolveRouterParams({ args, app: this.app });
  const middlewares = splited.middlewares;
  // 取出 controller
  const controller = splited.middlewares.pop();

  let name = '';
  let prefix = '';
  if (splited.prefix.length === 2) {
    // router.get(name, url)
    name = splited.prefix[0];
    prefix = splited.prefix[1];
  } else {
    // router.get(url)
    prefix = splited.prefix[0];
  }

  for (const key in REST_MAP) {
    const action = controller[key];
    if (!action) continue; // 是否实现了规则

    const opts = REST_MAP[key];
    let formatedName;
    if (opts.member) {
      formatedName = inflection.singularize(name);
    } else {
      formatedName = inflection.pluralize(name);
    }
    if (opts.namePrefix) {
      formatedName = opts.namePrefix + formatedName;
    }
    prefix = prefix.replace(/\/$/, '');
    const path = opts.suffix ? `${prefix}/${opts.suffix}` : prefix;
    const method = Array.isArray(opts.method) ? opts.method : [ opts.method ];
    this.register(path, method, middlewares.concat(action), { name: formatedName });
  }

  return this;
}

module.exports = {
  restful,
};
